package com.watson.db.config;


import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.StringValue;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author watson
 * @Date 2022/7/6 20:59
 * @Description:  MybatisPlus配置类
 * @Version 1.0
 */
@Configuration
public class MybatisPlusConfig {

    /**
     * 新多租户插件配置,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存万一出现问题
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {

            /**
             * 这里返回的租户id作为sql执行时自动添加的租户id
             * 这里的租户id可以从线程本地变量中获取（当租户id提前设置到了线程本地变量中），
             * 也可以从请求环境中获取（当租户id在请求环境中存在时）
             * 为了简化演示，这里设置了一个固定值
             * @return
             */
            @Override
            public Expression getTenantId() {
                return new LongValue(1);
            }

            // 这是 default 方法,默认返回 false 表示所有表都需要拼多租户条件
            @Override
            public boolean ignoreTable(String tableName) {
                return !"user".equalsIgnoreCase(tableName);
            }
        }));
        // 如果用了分页插件注意先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
        // 用了分页插件必须设置 MybatisConfiguration#useDeprecatedExecutor = false
//        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }

//    @Bean
//    public ConfigurationCustomizer configurationCustomizer() {
//        return configuration -> configuration.setUseDeprecatedExecutor(false);
//    }

        /**
         * 分页插件
         *
         * @return
         */
        @Bean
        public PaginationInterceptor paginationInterceptor() {
            PaginationInterceptor paginationInterceptor = new PaginationInterceptor();

            // 创建SQL解析器集合
            List<ISqlParser> sqlParserList = new ArrayList<>();

            // 创建租户SQL解析器
            TenantSqlParser tenantSqlParser = new TenantSqlParser();

            // 设置租户处理器
//            tenantSqlParser.setTenantHandler(new TenantHandler() {
//                @Override
//                public Expression getTenantId() {
//                    // 设置当前租户ID，实际情况你可以从cookie、或者缓存中拿都行
//                    return new StringValue("jiannan");
//                }
//
//                @Override
//                public String getTenantIdColumn() {
//                    // 对应数据库租户ID的列名
//                    return "tenant_id";
//                }
//
//                @Override
//                public boolean doTableFilter(String tableName) {
//                    // 是否需要需要过滤某一张表
//              /*  List<String> tableNameList = Arrays.asList("sys_user");
//                if (tableNameList.contains(tableName)){
//                    return true;
//                }*/
//                    return false;
//                }
//            });

            sqlParserList.add(tenantSqlParser);
            paginationInterceptor.setSqlParserList(sqlParserList);

            paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
                @Override
                public boolean doFilter(MetaObject metaObject) {
                    MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
                    // 对应Mapper、dao中的方法
                    //方式一：在配置分页插件中加上配置ISqlParserFilter解析器，如果配置SQL很多，比较麻烦，不建议。
                    if("com.example.demo.mapper.UserMapper.selectList".equals(ms.getId())){
                        return true;
                    }
                    return false;
                }
            });


            return paginationInterceptor;
        }

    }

